#include <config.h>
#include <fonts_manager.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <wchar.h>

#include <debug_manager.h>

/* 函数原型需要满足PT_FontOpr中的函数指针类型 */
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize);
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static int FreeTypeSetFontSize(unsigned int dwFontSize);

static T_FontOpr g_tFreeTypeFontOpr = {
	.name          = "freetype",
	.FontInit      = FreeTypeFontInit,  /* 确保类型匹配 */
	.GetFontBitmap = FreeTypeGetFontBitmap,
	.SetFontSize   = FreeTypeSetFontSize,  /* 确保类型匹配 */
};

static FT_Library g_tLibrary;
static FT_Face g_tFace;
static FT_GlyphSlot g_tSlot;
static int g_iSize;  /* 当前字体大小 */

/**********************************************************************
 * 函数名称： FreeTypeFontInit
 * 功能描述： 初始化FreeType字体模块
 * 输入参数： pcFontFile - 字体文件名,含路径
 *            dwFontSize - 字体大小
 * 输出参数： 无
 * 返 回 值： 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize)
{
	int iError;

	/* 初始化FT库 */
	iError = FT_Init_FreeType(&g_tLibrary);
	if (iError)
	{
		DBG_PRINTF("FT_Init_FreeType failed: %d\n", iError);
		return -1;
	}
	
	/* 加载字体文件 */
	iError = FT_New_Face(g_tLibrary, pcFontFile, 0, &g_tFace);
	if (iError == FT_Err_Unknown_File_Format)
	{
		DBG_PRINTF("Font format unsupported\n");
		return -1;
	}
	else if (iError)
	{
		DBG_PRINTF("Cannot open font file %s, error = %d\n", pcFontFile, iError);
		return -1;
	}
	
	/* 设置字体为Unicode编码，支持中文 */
	iError = FT_Select_Charmap(g_tFace, FT_ENCODING_UNICODE);
	if (iError)
	{
		DBG_PRINTF("Cannot set font to Unicode encoding, falling back to default\n");
		/* 继续使用默认编码，不要退出 */
	}

	/* 获取字体插槽 */
	g_tSlot = g_tFace->glyph;
	
	/* 设置初始字体大小 */
	FreeTypeSetFontSize(dwFontSize);
	
	return 0;
}

/**********************************************************************
 * 函数名称： FreeTypeGetFontBitmap
 * 功能描述： 获得字符的位图, 位图是1个字节1个像素
 * 输入参数： dwCode       - 字符的编码值(ASCII、GBK、UTF8)
 * 输出参数： ptFontBitMap - 内含位图信息
 * 返 回 值： 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
    int iError;
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;
    static int iHasWarnedForCode[256] = {0}; // 记录已警告过的字符代码

    /* 特殊处理空格和删除字符 */
    if (dwCode == 0x20 || dwCode == 0x7f)
    {
        /* 设置空格的宽度为当前字体大小的1/3 */
        int iSpaceWidth = g_iSize / 3;
        if (iSpaceWidth < 4) iSpaceWidth = 4;

        /* 设置空格字符的位图信息 */
        ptFontBitMap->iXLeft    = iPenX;
        ptFontBitMap->iYTop     = iPenY - g_iSize/2;  /* 垂直居中 */
        ptFontBitMap->iXMax     = iPenX + iSpaceWidth;
        ptFontBitMap->iYMax     = iPenY + g_iSize/2;
        ptFontBitMap->iBpp      = 8;
        ptFontBitMap->iPitch    = iSpaceWidth;
        ptFontBitMap->pucBuffer = NULL;  /* 空格没有可见内容 */
        
        /* 设置下一个字符的位置 */
        ptFontBitMap->iNextOriginX = iPenX + iSpaceWidth;
        ptFontBitMap->iNextOriginY = iPenY;
        
        return 0;
    }
    
    /* 替换不可显示的控制字符 */
    if (dwCode < 32 && dwCode != '\t' && dwCode != '\n' && dwCode != '\r')
    {
        dwCode = 0x20;  /* 用空格替代控制字符 */
    }

    /* 设置字体渲染参数 */
    FT_Set_Pixel_Sizes(g_tFace, g_iSize, g_iSize);
    
    /* 加载字符图像 */
    iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL);
    
    /* 处理错误情况 */
    if (iError)
    {
        /* 只为每个代码打印一次警告 */
        if (dwCode < 256 && !iHasWarnedForCode[dwCode])
        {
            DBG_PRINTF("FT_Load_Char error for code : 0x%x\n", dwCode);
            iHasWarnedForCode[dwCode] = 1;
        }
        
        /* 使用一个标准宽度的空位图代替 */
        ptFontBitMap->iXLeft    = iPenX;
        ptFontBitMap->iYTop     = iPenY - g_iSize/2;
        ptFontBitMap->iXMax     = iPenX + g_iSize/2;
        ptFontBitMap->iYMax     = iPenY + g_iSize/2;
        ptFontBitMap->iBpp      = 8;
        ptFontBitMap->iPitch    = g_iSize/2;
        ptFontBitMap->pucBuffer = NULL;
        ptFontBitMap->iNextOriginX = iPenX + g_iSize/2;
        ptFontBitMap->iNextOriginY = iPenY;
        return 0;
    }

    /* 如果位图无效（零宽度或零高度），使用空位图 */
    if (!g_tSlot->bitmap.buffer || g_tSlot->bitmap.width <= 0 || g_tSlot->bitmap.rows <= 0)
    {
        /* 只为每个代码打印一次警告 */
        if (dwCode < 256 && !iHasWarnedForCode[dwCode])
        {
            DBG_PRINTF("Invalid bitmap dimensions for code 0x%x, using space instead\n", dwCode);
            iHasWarnedForCode[dwCode] = 1;
        }
        
        /* 使用一个标准宽度的空位图代替 */
        ptFontBitMap->iXLeft    = iPenX;
        ptFontBitMap->iYTop     = iPenY - g_iSize/2;
        ptFontBitMap->iXMax     = iPenX + g_iSize/2;
        ptFontBitMap->iYMax     = iPenY + g_iSize/2;
        ptFontBitMap->iBpp      = 8;
        ptFontBitMap->iPitch    = g_iSize/2;
        ptFontBitMap->pucBuffer = NULL;
        ptFontBitMap->iNextOriginX = iPenX + g_iSize/2;
        ptFontBitMap->iNextOriginY = iPenY;
        return 0;
    }
    
    /* 设置位图信息 */
    ptFontBitMap->iXLeft    = iPenX + g_tSlot->bitmap_left;
    ptFontBitMap->iYTop     = iPenY - g_tSlot->bitmap_top;
    ptFontBitMap->iXMax     = ptFontBitMap->iXLeft + g_tSlot->bitmap.width;
    ptFontBitMap->iYMax     = ptFontBitMap->iYTop + g_tSlot->bitmap.rows;
    ptFontBitMap->iBpp      = 8;
    ptFontBitMap->iPitch    = g_tSlot->bitmap.pitch;
    ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer;
    
    /* 设置下一个字符的位置，对中文字符增加额外间距 */
    int iAdvance = g_tSlot->advance.x >> 6;
    if (dwCode > 0x7F)  /* 中文字符 */
    {
        iAdvance += g_iSize / 4;  /* 增加1/4字体大小的间距 */
    }
    ptFontBitMap->iNextOriginX = iPenX + iAdvance;
    ptFontBitMap->iNextOriginY = iPenY;

    return 0;
}

/**********************************************************************
 * 函数名称： FreeTypeSetFontSize
 * 功能描述： 设置字符的尺寸(单位:色素)
 * 输入参数： dwFontSize - 字符的尺寸(单位:色素)
 * 输出参数： 无
 * 返 回 值： 0 - 成功, 其他值 - 失败
 ***********************************************************************/
static int FreeTypeSetFontSize(unsigned int dwFontSize)
{
    int iError;
    
    g_iSize = dwFontSize;  /* 更新当前字体大小 */
    iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
    if (iError)
    {
        DBG_PRINTF("FT_Set_Pixel_Sizes error : %d\n", dwFontSize);
        return -1;
    }
    
    return 0;
}

/**********************************************************************
 * 函数名称： FreeTypeInit
 * 功能描述： 注册"FreeType字体模块"
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int FreeTypeInit(void)
{
	return RegisterFontOpr(&g_tFreeTypeFontOpr);
}